from decimal import ROUND_HALF_UP, Decimal, InvalidOperation
import re
from django.conf import settings
from rest_framework import serializers
from .models import DjDish, DjDishCategory, DjDishImage


class ConsumerDishSerializer(serializers.ModelSerializer):
    """消费端菜品序列化器"""
    category_name = serializers.CharField(source='category.name', read_only=True)
    
    class Meta:
        model = DjDish
        fields = [
            'id', 'name', 'description', 'price', 
            'image', 'is_spicy', 'prep_time',
            'category', 'category_name'
        ]
        extra_kwargs = {
            'category': {'write_only': True}  # 消费端只需读分类名
        }


class DishSerializer(serializers.ModelSerializer):
    # 新增：获取菜品图片（优先取主图，没有则取第一张）
    image = serializers.SerializerMethodField()

    class Meta:
        model = DjDish
        fields = ['id', 'name', 'description', 'category_id',
                  'display_price', 'image']

    def get_image(self, obj):
        """从关联的图片中提取URL"""
        # 获取所有审核通过的图片
        images = obj.original_images.all()
        if not images:
            return None  # 没有图片时返回None
        
        # 优先取主图
        primary_image = images.filter(is_primary=True).first()
        if primary_image:
            return self._get_image_url(primary_image.image)
        
        # 没有主图则取第一张
        first_image = images.first()
        return self._get_image_url(first_image.image) if first_image else None

    def _get_image_url(self, image_field):
        """获取图片的完整URL"""
        request = self.context.get('request')
        if request and image_field:
            return request.build_absolute_uri(image_field.url)
        return None
        
class DishCategorySerializer(serializers.ModelSerializer):
    available_dishes = DishSerializer(many=True, read_only=True)

    class Meta:
        model = DjDishCategory
        fields = '__all__'

class DishImageSerializer(serializers.ModelSerializer):
    image_url = serializers.SerializerMethodField()

    def get_image_url(self, obj):
        # 安全访问图片URL
        if hasattr(obj.image, 'url'):
            url = obj.image.url
            # 确保返回完整URL
            if url.startswith(('http://', 'https://')):
                return url
            return f"http://127.0.0.1:8000{obj.image.url}"
        return None
    class Meta:
        model = DjDishImage
        fields = ['id', 'image_url', 'is_primary', 'sort_order']
        extra_kwargs = {
            'image': {'required': False},
            'dish': {'required': False}  # 允许不传递dish
        }
    def validate(self, attrs):
        # 确保至少提供一种图片
        if not attrs.get('image') and not attrs.get('cloud_file_id'):
            raise serializers.ValidationError("必须提供图片或云文件ID")
        return attrs



# serializers.py
class DishCreateUpdateSerializer(serializers.ModelSerializer):
    base_price = serializers.DecimalField(
        max_digits=8,
        decimal_places=2,
        min_value=Decimal('0.01'),
        error_messages={
            'min_value': '价格必须大于0'
        }
    )
    
    class Meta:
        model = DjDish
        fields = ['id','name', 'base_price', 'category', 'description', 
                 'is_spicy', 'is_vegetarian', 'prep_time', 'dish_images']
        extra_kwargs = {
            'dish_images': {'required': False}
        }
        
    def validate_base_price(self, value):
        # 1. 处理空值
        if value is None or (isinstance(value, str) and value.strip() == ""):
            raise serializers.ValidationError("价格不能为空")
        
        # 2. 处理字符串类型的价格
        if isinstance(value, str):
            # 移除所有非数字、非小数点、非负号的字符
            cleaned_value = re.sub(r"[^\d.-]", "", value.strip())
            
            # 检查是否有多个小数点，只保留第一个
            if cleaned_value.count('.') > 1:
                first_dot = cleaned_value.index('.')
                cleaned_value = cleaned_value[:first_dot+1] + cleaned_value[first_dot+1:].replace('.', '')
            
            # 处理空字符串或仅保留符号的情况
            if not cleaned_value or cleaned_value in [".", "-", "-."]:
                raise serializers.ValidationError("价格格式无效，请输入数字（例如：19.99）")
            
            value = cleaned_value
        
        # 3. 转换为 Decimal 并验证
        try:
            price = Decimal(str(value))
        except InvalidOperation:
            raise serializers.ValidationError(f"价格格式无效：{value}（请输入正确的数字）")
        
        # 4. 验证价格是否大于0
        if price <= 0:
            raise serializers.ValidationError("价格必须大于0")
        
        # 5. 安全地保留两位小数
        try:
            # 正常情况：直接量化为两位小数
            return price.quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
        except InvalidOperation:
            # 异常情况：使用替代方案确保两位小数
            # 先将价格乘以100取整，再除以100（强制保留两位小数）
            scaled = (price * Decimal('100')).to_integral_value(rounding=ROUND_HALF_UP)
            rounded_price = scaled / Decimal('100')
            return rounded_price
        
class DjDishCategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = DjDishCategory
        fields = '__all__'
        extra_kwargs = {
            'image': {'required': False},  # API不强制要求图片
            'name': {'allow_blank': False}
        }
    
    def validate(self, data):
        """自定义验证逻辑"""
        if not data.get('name', '').strip():
            raise serializers.ValidationError("分类名称不能为空")
        return data

#厨师端后台部分


class VdjDishCategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = DjDishCategory
        fields = ['id', 'name', 'name_en', 'image', 'is_active', 'sort_order']

class VdjDishImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = DjDishImage
        fields = ['id', 'image', 'is_primary', 'sort_order']

class VdjDishSerializer(serializers.ModelSerializer):
    chef_name = serializers.CharField(source='chef.nickname', read_only=True)
    chef_phone = serializers.CharField(source='chef.phone_number', read_only=True)
    category = VdjDishCategorySerializer(read_only=True)
    images = VdjDishImageSerializer(many=True, read_only=True)
    
    class Meta:
        model = DjDish
        fields = [
            'id', 'name', 'description', 'base_price', 'display_price',
            'category', 'chef', 'chef_name', 'chef_phone',
            'provide_meal_service', 'provide_utensils', 'is_spicy',
            'is_vegetarian', 'prep_time', 'is_available', 'is_featured',
            'created_at', 'updated_at', 'images'
        ]

class VdjDishCreateUpdateSerializer(serializers.ModelSerializer):
    platform_fee_rate = serializers.DecimalField(
        max_digits=5, 
        decimal_places=2,
        write_only=True,
        required=False,
        default=0.20
    )
    
    class Meta:
        model = DjDish
        fields = [
            'name', 'description', 'base_price', 'category',
            'provide_meal_service', 'provide_utensils', 'is_spicy',
            'is_vegetarian', 'prep_time', 'is_available', 'platform_fee_rate'
        ]